package android.textIt.backend.dao;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import textapp.connector.message.SaveMessageResponse;
import android.content.Context;
import android.database.Cursor;
import android.textIt.backend.Properties;
import android.textIt.backend.database.DBProperties;
import android.textIt.backend.database.DatabaseHelper;
import android.textIt.backend.model.Group;
import android.textIt.backend.model.Message;
import android.textIt.backend.model.User;

import com.google.gson.Gson;

public class MessageDao {
  private final DatabaseHelper helper;

  public MessageDao(Context ctx) {
    helper = new DatabaseHelper(ctx);
  }

  public Message getMessageById(long id) {
    return new Message(helper.getByID(id, DBProperties.MESSAGE_TABLE), helper);
  }

  public void createMessage(Message m) {
    helper.createMessage(m);
  }

  public void deleteMessage(Message m) {
    helper.deleteByID(m.getId(), DBProperties.MESSAGE_TABLE);
  }

  public List<Message> getAllMessages() {
    Cursor c = helper.getAllEntries(DBProperties.MESSAGE_TABLE);
    ArrayList<Message> returnList = new ArrayList<Message>();
    if (c.getCount() > 0) {
      do {
        returnList.add(new Message(c, helper));
      }
      while (c.moveToNext());
    }
    for (Message m : returnList) {
      m.setSender(new User(helper.getByID(m.getSender().getId(), DBProperties.USER_TABLE)));
    }
    return returnList;
  }

  public List<Message> getAllMessagesWithUser(User u) {
    Cursor c = helper.getAllMessagesSentByUser(u);
    ArrayList<Message> returnList = new ArrayList<Message>();
    if (c.getCount() > 0) {
      do {
        returnList.add(new Message(c, helper));
      }
      while (c.moveToNext());
    }
    c = helper.getAllMessagesSentToUser(u);
    if (c.getCount() > 0) {
      do {
        returnList.add(new Message(c, helper));
      }
      while (c.moveToNext());
    }
    for (Message m : returnList) {
      m.setReceiver(new Group(u.getiGroup()));
      m.setSender(new User(helper.getByID(m.getSender().getId(), DBProperties.USER_TABLE)));
    }
    return returnList;
  }

  public List<Message> getAllMessagesSentbyUser(User u) {
    Cursor c = helper.getAllMessagesSentByUser(u);
    ArrayList<Message> returnList = new ArrayList<Message>();
    do {
      returnList.add(new Message(c, helper));
    }
    while (c.moveToNext());
    for (Message m : returnList) {
      m.setReceiver(new Group(u.getiGroup()));
      m.setSender(new User(helper.getByID(m.getSender().getId(), DBProperties.USER_TABLE)));
    }
    return returnList;
  }

  public List<Message> getAllMessagesSentToUser(User u) {
    Cursor c = helper.getAllMessagesSentToUser(u);
    ArrayList<Message> returnList = new ArrayList<Message>();
    do {
      returnList.add(new Message(c, helper));
    }
    while (c.moveToNext());
    for (Message m : returnList) {
      m.setReceiver(new Group(u.getiGroup()));
      m.setSender(new User(helper.getByID(m.getSender().getId(), DBProperties.USER_TABLE)));
    }
    return returnList;
  }

  public List<Message> getAllMessagesWithGroup(Group g) {
    Cursor c = helper.getAllMessagesSentToGroup(g);
    ArrayList<Message> returnList = new ArrayList<Message>();
    if (c.getCount() > 0) {
      do {
        returnList.add(new Message(c, helper));
      }
      while (c.moveToNext());
    }
    for (Message m : returnList) {
      m.setReceiver(g);
      m.setSender(new User(helper.getByID(m.getSender().getId(), DBProperties.USER_TABLE)));
    }
    return returnList;
  }

  public void sendMessage(Message m) {
    if (!Properties.useServer)
      return;
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(Properties.SERVER_URL + "/saveMessageJson");

    try {
      // Add your data
      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

      User u = new User(helper.getUsersInGroup(m.getReceiver()));
      nameValuePairs.add(new BasicNameValuePair("to", Long.toString(u.getReference_id())));
      nameValuePairs.add(new BasicNameValuePair("from", Long.toString(m.getSender()
                                                                       .getReference_id())));
      nameValuePairs.add(new BasicNameValuePair("type", "0"));
      nameValuePairs.add(new BasicNameValuePair("text", m.getContent()));
      nameValuePairs.add(new BasicNameValuePair("lifetime", "0"));
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

      // Execute HTTP Post Request
      HttpResponse response = httpclient.execute(httppost);
      String returnString = inputStreamToString(response.getEntity().getContent());

      SaveMessageResponse res = new Gson().fromJson(returnString, SaveMessageResponse.class);
      m.setReference_id(res.getBody().getId());
      helper.updateMessage(m);

    }
    catch (ClientProtocolException e) {
    }
    catch (IOException e) {
    }
  }

  public void sendGroupMessage(Message m) {
    if (!Properties.useServer)
      return;
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(Properties.SERVER_URL + "/saveGroupMessageJson");

    try {
      // Add your data
      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

      nameValuePairs.add(new BasicNameValuePair("togroup", Long.toString(m.getReceiver().getReference_id())));
      nameValuePairs.add(new BasicNameValuePair("from", Long.toString(m.getSender()
                                                                       .getReference_id())));
      nameValuePairs.add(new BasicNameValuePair("type", "0"));
      nameValuePairs.add(new BasicNameValuePair("text", m.getContent()));
      nameValuePairs.add(new BasicNameValuePair("lifetime", "0"));
      httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

      // Execute HTTP Post Request
      HttpResponse response = httpclient.execute(httppost);
      String returnString = inputStreamToString(response.getEntity().getContent());

      SaveMessageResponse res = new Gson().fromJson(returnString, SaveMessageResponse.class);
      m.setReference_id(res.getBody().getId());
      helper.updateMessage(m);

    }
    catch (ClientProtocolException e) {
    }
    catch (IOException e) {
    }
  }
  
  // Fast Implementation
  private String inputStreamToString(InputStream is) throws IOException {
    String line = "";
    StringBuilder total = new StringBuilder();

    // Wrap a BufferedReader around the InputStream
    BufferedReader rd = new BufferedReader(new InputStreamReader(is));

    // Read response until the end
    while ((line = rd.readLine()) != null) {
      total.append(line);
    }

    // Return full string
    return total.toString();
  }

}
